package com.gitee.hermer.engine.jars.app.sdk.processor;

import java.lang.annotation.Annotation;
import java.net.URLClassLoader;
import java.util.Set;

import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.core.type.filter.AnnotationTypeFilter;

import com.gitee.hermer.engine.jars.app.sdk.proxy.ExecuteProxyFactory;

public class EngineAnnotationScanner extends ClassPathBeanDefinitionScanner {
	/**
	 * 实体类对应的AnnotationClazz
	 */
	private Class<? extends Annotation> selfAnnotationClazz;



	public Class<? extends Annotation> getSelfAnnotationClazz() {
		return selfAnnotationClazz;
	}

	public void setSelfAnnotationClazz(Class<? extends Annotation> selfAnnotationClazz) {
		this.selfAnnotationClazz = selfAnnotationClazz;
	}

	/**
	 * 传值使用的临时静态变量
	 */
	private static Class<? extends Annotation> staticTempAnnotationClazz = null;

	/**
	 * 传入指定的Annotation类
	 * @param registry
	 * @param clazz
	 * @return
	 */
	public static synchronized EngineAnnotationScanner getScanner(BeanDefinitionRegistry registry,Class<? extends Annotation> clazz){
		staticTempAnnotationClazz = clazz;
		EngineAnnotationScanner scanner = new EngineAnnotationScanner(registry);
		scanner.setSelfAnnotationClazz(clazz);
		return scanner;
	}

	private EngineAnnotationScanner(BeanDefinitionRegistry registry) {
		super(registry);
	}

	// 构造函数需调用函数，使用静态变量annotationClazz传值
	@Override
	public void registerDefaultFilters() {
		// 添加需扫描的Annotation Class
		this.addIncludeFilter(new AnnotationTypeFilter(staticTempAnnotationClazz));
	}

	@Override
	public Set<BeanDefinitionHolder> doScan(String... basePackages) {
		Set<BeanDefinitionHolder> holders =  super.doScan(basePackages);
		for (BeanDefinitionHolder holder : holders) {
			GenericBeanDefinition definition = (GenericBeanDefinition) holder.getBeanDefinition();
			URLClassLoader classLoader = null;
			try{
				Class clz = null;
				if(!definition.hasBeanClass()){
					clz = Class.forName(definition.getBeanClassName(),false,Thread.currentThread().getContextClassLoader());
				}else{
					clz = definition.getBeanClass();
				}
				
				if(clz.isInterface()){
					definition.getPropertyValues().add("proxyInterface", clz);
					definition.setBeanClass(ExecuteProxyFactory.class);
					definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
				}
			}catch (Exception e) {
				e.printStackTrace();
			}
		}
		return holders;
	}

	@Override
	public boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
		return beanDefinition.getMetadata().hasAnnotation(this.selfAnnotationClazz.getName());
	}
}